// 焦点管理器核心
(function (window) {
  'use strict';
  //基础配置信息
  var _defConfig = {
    keyMap: { 65: "LEFT", 37: "LEFT", 87: "UP", 38: "UP", 68: "RIGHT", 39: "RIGHT", 83: "DOWN", 40: "DOWN", 13: "ENTER", 32: "BACK", 8: "BACK", 36: "HOME", 12: "BACKSPACE", 280: "DEL", 287: "DEL", 18: "MENU", 48: 0, 49: 1, 50: 2, 51: 3, 52: 4, 53: 5, 54: 6, 55: 7, 56: 8, 57: 9, },
    switchClass: "focusSwitch",//焦点框架
    boxClass: "focusBox",//盒子
    scrollClass: "focusScroll",//滚动区域
    widgetClass: "focusWidget",//焦点元素
    marqueeClass: "focusMarquee",//跑马灯
    focusClass: "is-focus",//聚焦样式名
    darkFocusClass: "dark-focus",//暗焦样式名
  }
  // 工具方法 --------------------------------------------------
  var Utils = {
    find: function (list, fn) {
      var _itm = { index: -1, item: null };
      for (var i = 0; i < list.length; i++) {
        var _el = list[i];
        if (typeof fn === "function" && fn(_el, i)) {
          _itm.index = i;
          _itm.item = _el;
          break;
        }
      }
      return _itm;
    },
    filter: function (list, fn) {
      var _list = [];
      for (var i = 0; i < list.length; i++) {
        var _el = list[i];
        if (typeof fn === "function" && fn(_el, i)) {
          _list.push(_el);
        }
      }
      return _list;
    },
    forEach: function (list, callback) {
      for (var i = 0; i < list.length; i++) {
        (function (index) {
          callback(list[index], index, list);
        })(i);
      }
    },
    map: function (list, callback) {
      var _list = []
      for (var i = 0; i < list.length; i++) {
        (function (index) {
          _list.push(callback(list[index], index, list) || list[index])
        })(i);
      }
      return _list
    },
    nextTick: function (fn) { return setTimeout(fn, 0); },
    $: function (id) { return document.getElementById(id) },
    $class: function (classname, _dom) { return (_dom || document).getElementsByClassName(classname) },
    getCurrentStyle: function (element, styleProp) {
      if (element.currentStyle) {
        return element.currentStyle[styleProp];
      } else if (window.getComputedStyle) {
        return window.getComputedStyle(element, null).getPropertyValue(styleProp);
      } else {
        return element.style[styleProp];
      }
    },
    isEleHide: function (ele) {
      if (typeof ele === "string") ele = Utils.$(ele)
      if (ele.style.display === "none") return true
      if (ele.style.visibility === "hidden") return true
      if (Utils.getCurrentStyle(ele, "display") === "none") return true
      if (Utils.getCurrentStyle(ele, "visibility") === "hidden") return true
      if (ele.offsetWidth === 0 || ele.offsetHeight === 0) return true
      return false
    },
    requestAnimationFrame: function (step) {
      step = typeof step === "function" ? step : function () { };
      if (window.requestAnimationFrame) {
        return window.requestAnimationFrame(step);
      } else {
        return setInterval(step, 16);
      }
    },
    cancelAnimationFrame: function (id) {
      if (window.cancelAnimationFrame) {
        window.cancelAnimationFrame(id);
      } else {
        clearInterval(id);
      }
    },
    animate: function (element, targetPosition, duration, property, callback) {
      property = property || 'left';
      var startPosition = getElementStyle(element, property);
      var distance = targetPosition - startPosition;
      var startTime = new Date().getTime();
      var animationId;
      var _this = this;
      var step = function () {
        var elapsed = new Date().getTime() - startTime;
        var progress = elapsed / duration;
        progress = progress > 1 ? 1 : progress;
        element.style[property] = (startPosition + distance * progress) + 'px';
        if (progress < 1) {
          animationId = _this.requestAnimationFrame(step);
        } else {
          _this.cancelAnimationFrame(animationId);
          if (typeof callback === "function") {
            callback();
          }
        }
      };
      animationId = this.requestAnimationFrame(step);
      return animationId;
    },
    marqueeTimer: {

    },
    //停止文字滚动
    onStopMarquee: function (_id) {
      clearInterval(this.marqueeTimer)
      this.marqueeTimer = null
      var _this = this
      this.nextTick(function () {
        var _ele = _this.$(_id)
        if (!_ele) return
        var _marqueeList = _this.$class(_defConfig.marqueeClass, _ele)
        if (!_marqueeList || !_marqueeList[0]) return
        _this.forEach(_marqueeList, function (marqueeDom) {
          if (marqueeDom.scrollWidth <= marqueeDom.clientWidth) return
          var _content = _this.$class(_defConfig.marqueeClass + "-content", marqueeDom)
          if (!_content || !_content[0]) return
          _content[0].style.left = 0 + "px"
        })
      });
    },
    //文字滚动
    onMarquee: function (_id) {
      var _this = this, _marqueeList = []
      if (typeof _id === "string") { _marqueeList = [this.$(_id)] }
      else if (_id && _id.style && _id.classList) { _marqueeList = [_id] }
      if (!_marqueeList || !_marqueeList[0]) return
      this.nextTick(function () {
        clearInterval(_this.marqueeTimer[_id])
        delete _this.marqueeTimer[_id]
        var _list = [], _mar = 20
        _this.forEach(_marqueeList, function (marqueeDom) {
          if (marqueeDom.scrollWidth <= marqueeDom.clientWidth) return////
          var _contentId = _defConfig.marqueeClass + "-content"
          var _content = _this.$class(_contentId, marqueeDom)//修改dom结构，用于滚动
          if (!_content || !_content[0]) {
            var _html = marqueeDom.innerHTML
            var _newHtml = '<div class="' + _defConfig.marqueeClass + '-content-item" style="display:inline-block;padding-right:' + _mar + 'px;">' + _html + '</div>'
            marqueeDom.innerHTML = '<div class="' + _defConfig.marqueeClass + '-content" style="position: absolute;left:0;top:0;">' + _newHtml + _newHtml + '</div>'
            _content = _this.$class(_contentId, marqueeDom)
            if (!_content || !_content[0]) return
          }
          _content = _content[0]
          if (!_content) return
          var _itemDom = _this.$class(_defConfig.marqueeClass + "-content-item", marqueeDom)//修改dom结构，用于滚动
          if (!_itemDom || !_itemDom[0]) return
          _list.push({
            child: _content,
            itemDom: _itemDom[0],
          })
        })
        if (_list.length > 0) {
          _this.marqueeTimer[_id] = this.requestAnimationFrame(function () {
            _this.forEach(_list, function (val) {
              var _pos = val.child.style.left.replace("px", "")
              if (_pos < -val.itemDom.offsetWidth) { _pos = 0 }
              val.child.style.left = (_pos - 2) + "px"
            })
          }, 60);
        }
      });
    }
  };

  // 焦点框架核心 ----------------------------------------------
  function FocusFrame(params) {
    if (!params || !params.container) throw new Error('必须提供容器元素');
    this.config = {
      container: params.container,//当前页面的dom信息
      useKeyDown: params.useKeyDown == null ? true : params.useKeyDown,//是否使用内置的焦点监听
    };
    this.state = {
      switchList: [],//焦点框架列表
      popupList: [],//弹窗列表
      keyDownFns: {},//绑定的监听的函数
      locked: false,//焦点锁-这里锁住所有焦点
      currentFocus: null,
      focusStack: [],
    };

    this.init(params.container);
  }

  FocusFrame.prototype = {

  }
  //核心焦点逻辑
  function FocusFramework(params) {

  }

  FocusFramework.prototype = {
    init: function (container) {
      this.container = container;
      this.cacheElements();
      this.bindEvents();
    },

    cacheElements: function () {
      this.focusables = [];
      var nodes = this.container.getElementsByClassName(this.config.switchClass);
      for (var i = 0; i < nodes.length; i++) {
        if (!Utils.isElementHidden(nodes[i])) {
          this.focusables.push(nodes[i]);
        }
      }
    },

    bindEvents: function () {
      var self = this;
      document.addEventListener('keydown', function (e) {
        if (self.state.locked) return;
        var key = self.config.keyMap[e.keyCode];
        if (key) self.handleKey(key);
      });
    },

    handleKey: function (key) {
      var strategy = {
        LEFT: this.moveLeft.bind(this),
        RIGHT: this.moveRight.bind(this),
        UP: this.moveUp.bind(this),
        DOWN: this.moveDown.bind(this),
        ENTER: this.activate.bind(this)
      };
      if (strategy[key]) strategy[key]();
    },

    // 核心移动算法 -------------------------------------------
    moveHorizontal: function (direction) {
      var candidates = this.getVisibleElements();
      var currentIndex = candidates.indexOf(this.state.currentFocus);
      var nextIndex = this.calculateNextIndex(currentIndex, candidates.length, direction);
      this.setFocus(candidates[nextIndex]);
    },

    moveVertical: function (direction) {
      // 实现垂直方向逻辑（类似水平方向）
    },

    calculateNextIndex: function (current, total, dir) {
      if (dir === 'LEFT' || dir === 'UP') {
        return current > 0 ? current - 1 : total - 1;
      }
      return current < total - 1 ? current + 1 : 0;
    },

    // 焦点管理 -----------------------------------------------
    setFocus: function (element) {
      if (this.state.currentFocus) {
        this.state.currentFocus.classList.remove(this.config.focusClass);
      }
      element.classList.add(this.config.focusClass);
      this.state.currentFocus = element;
      this.scrollTo(element);
    },

    scrollTo: function (element) {
      var scrollParent = this.findScrollParent(element);
      if (!scrollParent) return;

      var targetPos = element.offsetLeft - scrollParent.offsetWidth / 2;
      Utils.animate(scrollParent, targetPos, 300, 'scrollLeft');
    },

    findScrollParent: function (element) {
      while (element.parentElement) {
        if (element.classList.contains(this.config.scrollClass)) {
          return element.parentElement;
        }
        element = element.parentElement;
      }
      return null;
    },

    getVisibleElements: function () {
      return this.focusables.filter(function (el) {
        return !Utils.isElementHidden(el);
      });
    }
  };

  // 公开API -------------------------------------------------
  window.FocusFramework = FocusFramework;

})(window);

// 使用示例
// var framework = new FocusFramework({
//   container: document.getElementById('main-container')
// });